package com.linb.pan.storage.engine.local;

import com.linb.pan.core.utils.FileUtil;
import com.linb.pan.storage.engine.core.AbstractStorageEngine;
import com.linb.pan.storage.engine.core.context.*;
import com.linb.pan.storage.engine.local.config.LocalStorageEngineConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.List;

@Component
@Slf4j
public class LocalStorageEngine extends AbstractStorageEngine {

    @Autowired
    private LocalStorageEngineConfig config;

    /**
     * 存储文件
     */
    @Override
    protected void doStore(StoreFileContext context) throws IOException {
        String basePath = config.getRootFilePath();
        String realFilePath = FileUtil.generateStoreFileRealPath(basePath, context.getFilename());
        FileUtil.writeStreamToFile(context.getInputStream(), new File(realFilePath), context.getTotalSize());
        context.setRealPath(realFilePath);
    }

    /**
     * 读取文件内容并写入到输出流中
     */
    @Override
    protected void doReadFile(ReadFileContext context) throws IOException {
        File file = new File(context.getRealPath());
        FileUtil.writeFileOutputStream(new FileInputStream(file), context.getOutputStream(), file.length());
    }

    /**
     * 执行文件分片合并动作
     */
    @Override
    protected void doMergeFile(MergeFileContext context) throws IOException {
        //1.获取基本路径
        String basePath = config.getRootFilePath();//前缀
        //2.拼接为完整路径
        String realPath = FileUtil.generateStoreFileRealPath(basePath, context.getFilename());
        log.info("即将合并:{}", realPath);
        //3.创建合并后的文件
        FileUtil.createFile(new File(realPath));
        //4.文件分片合并
        List<String> chunkPathList = context.getRealPathList();
        for (String chunkPath : chunkPathList) {
            FileUtil.appendWrite(Paths.get(realPath), new File(chunkPath).toPath());
        }
        //5.删除分片文件
        FileUtil.deleteFiles(chunkPathList);
        //6.回填realPath
        context.setRealPath(realPath);
    }

    /**
     * 执行保存文件分片
     */
    @Override
    protected void doStoreChunk(StoreFileChunkContext context) throws IOException {
        String basePath = config.getRootFileChunkPath();//前缀
        String realFilePath = FileUtil.generateStoreFileChunkRealPath(basePath, context.getIdentifier(), context.getChunkNumber());
        FileUtil.writeStreamToFile(context.getInputStream(), new File(realFilePath), context.getTotalSize());
        context.setRealPath(realFilePath);
    }

    /**
     * 批量删除文件
     */
    @Override
    protected void doDelete(DeleteFileContext context) throws IOException {
        FileUtil.deleteFiles(context.getRealFilePathList());
    }
}
